#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=8050;
int n;
int last;
int cnt[N];
struct node{
    int l;
    int r;
    int f;
}tr[N<<2];
void build(int rt,int l,int r){
    tr[rt].l=l;
    tr[rt].r=r;
    //多组数据 重新建树要清楚懒惰标记
    //标记也表示颜色
    tr[rt].f=-1;
    if(l==r){
        return;
    }
    int m=(l+r)>>1;
    build(rt<<1,l,m);
    build(rt<<1|1,m+1,r);
}
void pushdown(int rt){
    tr[rt<<1].f=tr[rt<<1|1].f=tr[rt].f;
    tr[rt].f=-1;
}
void update(int L,int R,int f,int l,int r,int rt){
    //染色区域大于节点区域
    if(L<=l && R>=r){
        tr[rt].f=f;
        return;
    }
    if(tr[rt].f!=-1){
        pushdown(rt);
    }
    int m=(l+r)>>1;
    if(L<=m){
        update(L,R,f,l,m,rt<<1);
    }
    if(R>m){
        update(L,R,f,m+1,r,rt<<1|1);
    }
}
void query(int l,int r,int rt){
    if(l==r){
        if(tr[rt].f!=-1 && tr[rt].f!=last){
            cnt[tr[rt].f]++;
        }
        last=tr[rt].f;
        return;
    }
    if(tr[rt].f!=-1){
        pushdown(rt);
    }
    int m=(l+r)>>1;
    query(l,m,rt<<1);
    query(m+1,r,rt<<1|1);
}
int main(void){
    //freopen("data.txt","r",stdin);
    while(~scanf("%d",&n)){
        memset(cnt,0,sizeof(cnt));
        build(1,1,N);
        int a,b,c;
        for(int i=0;i<n;i++){
            scanf("%d%d%d",&a,&b,&c);
            //左端点加1 比如1-2 3-4这两个区间是不连续的
            update(a+1,b,c,1,N,1);
        }
        //记录下一层节点的颜色
        last=-1;
        query(1,N,1);
        for(int i=0;i<N;i++){
            if(cnt[i]){
                printf("%d %d\n",i,cnt[i]);
            }
        }
        printf("\n");
    }
    return 0;
}